/**
 * @file table columns + actionColumns
 */
import { usePermission } from '@/hooks/web/usePermission';
import { isBoolean, isFunction, isNumber, isString } from '@/utils/is';
import { cloneDeep } from 'lodash-es';
import type { Ref, ComputedRef } from 'vue';
import { ref, unref, computed, watch, toRaw } from 'vue';
import { ACTION_COLUMN_FLAG, DEFAULT_ALIGN, INDEX_COLUMN_FLAG, PAGE_SIZE } from '../constant';
import { GetColumnsParams } from '../types/column';
import { PaginationProps } from '../types/pagination';
import { BasicColumn, BasicTableProps, SorterResult } from '../types/table';

function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]): void {
	const actionColumn = unref(propsRef).actionColumn;
	if (!actionColumn) return;

	const { fixed } = actionColumn;

	// 剔除掉columns里面的flag
	const otherAction = columns.find(column => column.flag?.toUpperCase() === ACTION_COLUMN_FLAG);
	if (!otherAction) {
		columns.push({
			...(fixed ? { fixed: 'right' } : {}),
			...actionColumn,
			flag: ACTION_COLUMN_FLAG,
		});
	}
}

/**
 * 1. 设置是否自动省略超过字符
 * 2. 根据 key|dataIndex 自动补全另一个
 */
//
function handleItemOfColumns(item: BasicColumn, ellipsis: boolean) {
	const { key, dataIndex } = item;
	if (!key && (isString(dataIndex) || isNumber(dataIndex))) {
		item.key = dataIndex;
	}
	if (!dataIndex && (isString(key) || isNumber(key))) {
		item.dataIndex = key;
	}
	item.align = item.align || DEFAULT_ALIGN;
	if (ellipsis) {
		if (!isBoolean(item.ellipsis)) {
			Object.assign(item, {
				ellipsis,
			});
		} else {
			item.ellipsis = ellipsis;
		}
	}
}

function handleItemWithFilter(item: BasicColumn, filteredInfo: Ref<Recordable>): void {
	const { key } = item;
	if (!key) {
		return;
	}
	const filtered = filteredInfo.value || {};
	item.filteredValue = filtered[key];
}

function handleItemWithSorter(item: BasicColumn, sorteredInfo: Ref<SorterResult>): void {
	const { sorter } = item;
	if (!sorter) {
		return;
	}
	// TODO: 重置按钮同时重置排序条件
	const sorted = sorteredInfo.value;
	console.log(sorted);
}

function handleIndexColumn(
	propsRef: ComputedRef<BasicTableProps>,
	getPaginationRef: ComputedRef<boolean | PaginationProps>,
	columns: BasicColumn[],
) {
	const { showIndexColumn, indexColumnProps, isTreeTable } = unref(propsRef);

	let pushIndexColumns = false;
	if (unref(isTreeTable)) {
		return;
	}
	// columns.forEach(() => {
	const indIndex = columns.findIndex(column => column.flag?.toUpperCase() === INDEX_COLUMN_FLAG);
	if (showIndexColumn) {
		pushIndexColumns = indIndex === -1;
	} else if (!showIndexColumn && indIndex !== -1) {
		columns.splice(indIndex, 1);
	}
	// });

	if (!pushIndexColumns) return;

	const isFixedLeft = columns.some(item => item.fixed === 'left');

	columns.unshift({
		flag: INDEX_COLUMN_FLAG,
		width: 80,
		title: '序号',
		align: 'center',
		customRender: ({ index }) => {
			const getPagination = unref(getPaginationRef);
			if (isBoolean(getPagination)) {
				return `${index + 1}`;
			}
			const { current = 1, pageSize = PAGE_SIZE } = getPagination;
			return ((current < 1 ? 1 : current) - 1) * pageSize + index + 1;
		},
		...(isFixedLeft
			? {
					fixed: 'left',
			  }
			: {}),
		...indexColumnProps,
	});
}

// 设置是否显示
function isShow(column: BasicColumn): boolean {
	let isShowColumn = column.isShow ?? true;
	if (isFunction(isShowColumn)) {
		isShowColumn = isShow(column);
	}
	return isShowColumn;
}

export function useColumns(
	propsRef: ComputedRef<BasicTableProps>,
	paginationRef: ComputedRef<PaginationProps | boolean>,
	filteredInfo: Ref<Recordable | undefined>,
	sorteredInfo: Ref<any>,
) {
	const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>;
	// let cacheColumns = unref(propsRef).columns;

	// 先处理columns
	const getColumnsRef = computed(() => {
		const columns = cloneDeep(unref(columnsRef));

		handleIndexColumn(propsRef, paginationRef, columns);
		handleActionColumn(propsRef, columns);

		if (!columns) {
			return [];
		}

		// 超过宽度是否自动省略
		const { ellipsis, resetWithTableSearchInfo } = unref(propsRef);

		columns.map(item => {
			// 但凡有以下2个，则无需设置ellipsis
			const { customRender, filters, sorter } = item;
			handleItemOfColumns(item, Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender);
			resetWithTableSearchInfo && filters && handleItemWithFilter(item, filteredInfo as Ref<Recordable>);
			resetWithTableSearchInfo && sorter && handleItemWithSorter(item, sorteredInfo);
		});

		return columns;
	});

	const { hasPermission } = usePermission();

	// 筛选出需要展示的
	const getViewColumns = computed(() => {
		const viewColumns = sortFixedColumn(unref(getColumnsRef));

		const columns = cloneDeep(viewColumns);

		return columns.filter(column => {
			return hasPermission(column.auth) && isShow(column);
		});
		// .map(column => {
		//     // TODO: 处理editCell, format, antd@3.x 版本移除了slots属性
		// 	const {slots} = column

		// 	// 处理slots:{title: xxx}的情况
		// 	if(!slots || !slots?.title) {

		// 	}
		// })
	});

	function getColumns(opts?: GetColumnsParams) {
		const { ignoreIndex, ignoreAction, sort } = opts || {};
		let columns = toRaw(unref(getColumnsRef));
		if (ignoreIndex) {
			columns = columns.filter(item => item.flag !== INDEX_COLUMN_FLAG);
		}
		if (ignoreAction) {
			columns = columns.filter(column => column.flag?.toUpperCase() !== ACTION_COLUMN_FLAG);
		}
		if (sort) {
			columns = sortFixedColumn(columns);
		}
		return columns;
	}

	/**
	 * @description
	 * columnsRef的默认值为undefined，
	 * 当useTable中使用setProps后，propsRef的值更改，当columns有值，即不再是undefined，就会执行
	 * 所以无需判断 newColumns是否有值
	 */
	watch(
		() => unref(propsRef).columns,
		newColumns => {
			// props变化 -> getColumnsRef计算属性变化 -> getViewColumns计算属性变化
			columnsRef.value = newColumns;
			// TODO: 动态修改columns? setColumns
			// cacheColumns = newColumns?.filter(item => !item.flag) ?? [];
		},
	);

	return {
		getColumnsRef,
		getViewColumns,
		getColumns,
	};
}

function sortFixedColumn(columns: BasicColumn[]) {
	const fixedLeftColumns: BasicColumn[] = [];
	const fixedRightColumns: BasicColumn[] = [];
	const defColumns: BasicColumn[] = [];
	for (const column of columns) {
		if (column.fixed === 'left') {
			fixedLeftColumns.push(column);
			continue;
		}
		if (column.fixed === 'right') {
			fixedRightColumns.push(column);
			continue;
		}
		defColumns.push(column);
	}
	return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter(item => !item.defaultHidden);
}
